package com.sap.cloud.fleet

import com.sap.cloud.util.net.HttpBot;

class FleetController {
    private String peers
    public FleetController(String peers) {
        // e.g. 10.58.136.164
        this.peers = peers
    }

    public Map getClusterLoad() {
        def load = ['peers': [], 'current': 0, 'max': 0]

        def rc = exec(mkuri(this.peers), 'fleetctl list-machines | grep role=slave')
        load.peers = rc.collect {
            def peer = ['name': '', 'current': 0, 'max': 0, 'error': '']
            def tokens = it.split('\t')

            peer.name = tokens[1]
            try {
                peer.max = tokens[2].split(',').find{ it.startsWith('maxpod=') }.split('=')[1].toInteger()
                peer.current = exec(mkuri(peer.name), 'docker ps -a | grep hdb- | grep Server | wc -l')[0].toInteger()
            } catch (Exception e) {
                peer.error = e.getMessage()
            }

            return peer
        }

        load.current = load.peers.sum{ it.current }
        load.max = load.peers.sum{ it.max }

        return load
    }

    public String findNextNode() {
        def load = getClusterLoad()
        if (load.current >= load.max) {
            throw new RuntimeException("Cloud service is overloaded; (${load.current}/${load.max})")
        }

        def next = load.peers.takeWhile{ it.current < it.max }.min{ it.current }

        return next.name
    }

    private static String mkuri(String raw) {
        return "http://${raw}:3003"
    }

    private static String[] exec(String host, String cmd) {
        def rc = HttpBot.post(host, null, "exec '${cmd}'")
        if (rc.getStatus() != 200) {
            throw new RuntimeException(rc.getBody())
        }
        return rc.getBody().split('\n').drop(1)
    }
}
